package com.gopay.solution.service.manage.impl;

import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.solution.SolutionTypeConstant;
import com.gopay.common.constants.trans.TranSpCustType;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.acps.AcctProd;
import com.gopay.common.domain.acps.AcpsAcctMast;
import com.gopay.common.exception.validator.GopayCheckException;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.solution.vo.*;
import com.gopay.solution.common.constant.OprLevel;
import com.gopay.solution.dao.smelly.AcpsAcctMastTempQueryDAO;
import com.gopay.solution.domain.po.*;
import com.gopay.solution.domain.vo.Solution;
import com.gopay.solution.manager.*;
import com.gopay.solution.service.manage.PerSoluManageService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.gopay.common.constants.solution.SolutionTypeConstant.TRANS_FEE;

/**
 * 个性化配置管理接口实现类
 * 
 * @PerSoluManageServiceImpl.java
 * @author MA HUAN
 * @2013-5-22 下午4:38:25 www.gopay.com.cn Inc.All rights reserved.
 */
@Service("perSoluManageService")
public class PerSoluManageServiceImpl implements PerSoluManageService {
    @Resource(name = "ssApSolutionManager")
    private SsApSolutionManager ssApSolutionManager;
    
    @Resource(name = "ssAcctSolutionManager")
    private SsAcctSolutionManager ssAcctSolutionManager;

    @Resource(name = "ssPeSolutionManager")
    private SsPeSolutionManager ssPeSolutionManager;

    @Resource(name = "acpsAcctMastTempQueryDAO")
    private AcpsAcctMastTempQueryDAO acpsAcctMastTempQueryDAO;

    @Resource(name = "ssTransSoluManager")
    private SolutionManager ssTransSoluManager;
    
    @Resource(name = "ssTbSolutionManager")
    private SsTbSolutionManager ssTbSolutionManager;
    
    @Resource(name = "ssTransBasicSoluManager")
    private SolutionManager ssTransBasicSoluManager;

    @Resource(name = "solutionManagerMap")
    private Map<String , Object> solutionManagerMap;

    @Resource(name = "ssTransFeeSoluManager")
    private SolutionManager ssTransFeeSoluManager;

    @Resource(name = "ssTransPayChanSoluManager")
    private SolutionManager ssTransPayChanSoluManager;

    @Resource(name = "ssTransSettleSoluManager")
    private SolutionManager ssTransSettleSoluManager;

    private  final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Override
    public PerSoluTranInfo findPerSoluTranInfo(String acctId) {

        // 查找账户信息
        AcpsAcctMast acct = acpsAcctMastTempQueryDAO.find(AcpsAcctMast.class, acctId);
        if (acct == null) {
            // 暂时不做处理，返回空即可
            return null;
        }
        // 查找账户所属账户产品的交易方案信息
        SsApSolutionRel rel = ssApSolutionManager.findRelByProdCode(acct.getProdCode().toString(),
                SolutionTypeConstant.TRANS_TRN);
        if (rel == null) {
            // 暂时不做处理，返回空即可
            return null;
        }

        // 查找交易方案
        Solution solu = ssTransSoluManager.load(rel.getSolutionId());
        if (solu == null) {
            // 暂时不做处理，返回空即可
            return null;
        }

        List<TransDtlInfo> transDtlInfos = new ArrayList<TransDtlInfo>();
        List<SolutionRuleDtl> rules = solu.getRuleDtls();
        if (rules != null) {
            for (SolutionRuleDtl rule : rules) {
                SsTransDtl ruleDtl = (SsTransDtl) rule;
                TransDtlInfo dtl = new TransDtlInfo();
                dtl.setGopayIntTxnCd(ruleDtl.getGopayIntTxnCd());
                dtl.setAvaliable(true);// 因为交易方案不允许个性化，所以这里只会列出账户产品现行交易方案，不会有不可用的交易
                
                transDtlInfos.add(dtl);
            }
        }

        PerSoluTranInfo ret = new PerSoluTranInfo();
        ret.setPersonalized(false);
        ret.setTransDtlInfos(transDtlInfos);
        return ret;
    }

    @Override
    public SsTranBasicSolution findTranBasicSolu(String acctId, String gopayIntTxnCd) {
        
        Solution solu = null;
        boolean isPersonalized = false;

        SsAcctSolutionRel rel = ssPeSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_BASIC);
        //如果有个性化方案，则直接取该方案
        if(rel != null) {
            solu = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(rel.getSolutionId(), gopayIntTxnCd);
            if(solu != null && solu.getRuleDtls() != null && solu.getRuleDtls().size() > 0) {
                isPersonalized = true;
            }
        }
           
        //如果账户没有个性化交易基础方案，则读取本账户所属账户产品交易基础方案
        if(!isPersonalized){
            AcpsAcctMast acct = acpsAcctMastTempQueryDAO.find(AcpsAcctMast.class, acctId);
            if(acct != null) {
             // 查找账户所属账户产品的交易方案信息
             SsApSolutionRel apRel = ssApSolutionManager.findRelByProdCode(acct.getProdCode().toString(), SolutionTypeConstant.TRANS_BASIC);
             if(null != apRel){
            	 //查找账户产品的交易基础方案
            	 solu = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(apRel.getSolutionId(), gopayIntTxnCd);
             }
            }
        }
        if(null == solu){// 通用方案未设定时
            return null;
        }
        // add by zhaoxubing 20170802
        return getSsTranBasicSolution(acctId, solu, isPersonalized, rel);
    }

    private SsTranBasicSolution getSsTranBasicSolution(String acctId, Solution solu, boolean isPersonalized, SsAcctSolutionRel rel) {

        SsTranBasicSolution ret = new SsTranBasicSolution();
        List<SolutionRuleDtl> ruleDtls = solu.getRuleDtls();
        if(ruleDtls != null && ruleDtls.size() > 0) {
            //交易基础方案的某一个交易只允许有一条记录
            SsTransBasicDtl ruleDtl = (SsTransBasicDtl)ruleDtls.get(0);
            String gopayIntTxnCd = ruleDtl.getGopayIntTxnCd();
            ret.setPersonalized(isPersonalized);
            ret.setGopayIntTxnCd(gopayIntTxnCd);
            ret.setSolutionId(solu.getMeta().getSolutionId());
            ret.setSolutionCode(solu.getMeta().getSolutionCode());
            ret.setSolutionVersion(solu.getMeta().getSolutionVersion());
            ret.setSolutionName(solu.getMeta().getSolutionName());
            ret.setSolutionDesc(solu.getMeta().getSolutionDesc());

            TranBasicDtlInfo rule = new TranBasicDtlInfo();
            rule.setGopayIntTxnCd(gopayIntTxnCd);
            rule.setIsEnable(ruleDtl.getIsEnable());
            rule.setFeePayer(ruleDtl.getFeePayer());
            rule.setSettleCirCle(ruleDtl.getSettleCirCle());
            rule.setIsRefundFee(ruleDtl.getIsRefundFee());
            rule.setLegalIncomeAcct(ruleDtl.getLegalIncomeAcct());
            rule.setIsOptimizingSettle(ruleDtl.getIsOptimizingSettle());
            if(StringUtils.isNotEmpty(ruleDtl.getTranSpCustType())) {
                rule.setTranSpCustType(TranSpCustType.getTranSpCustTypeByValue(ruleDtl.getTranSpCustType()));
            }
            rule.setRefundPeriod(ruleDtl.getRefundPeriod());
            rule.setIsOptimizingSettle(ruleDtl.getIsOptimizingSettle());
            rule.setIsMobileNotify(ruleDtl.getIsMobileNotify());//短信通知

            rule.setIsOverTimeRefund(ruleDtl.getIsOverTimeRefund());
            rule.setEndRefundPeriod(ruleDtl.getEndRefundPeriod());
            //D1优化 add by lianpeng 20170717 begin
            rule.setSettlementType(ruleDtl.getSettlementType());
            rule.setSettlementOperationType(ruleDtl.getSettlementOperationType());
            //D1优化 add by lianpeng 20170717 end

            // add by zhaoxubing 20170328 begin
            if(IntTxnCd._00701.value.equals(gopayIntTxnCd)){ // 如果是退款转账交易，取收款退款的退款期限
                Solution solu01203 = null;
                boolean isPersonalized01200 = false;

                SsAcctSolutionRel rel01200 = ssPeSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_BASIC);
                //如果有个性化方案，则直接取该方案
                if(rel01200 != null) {
                    solu01203 = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(rel.getSolutionId(), IntTxnCd._01203.value);
                    if(solu01203 != null && solu01203.getRuleDtls() != null && solu01203.getRuleDtls().size() > 0) {
                        isPersonalized01200 = true;
                    }
                }

                //如果账户没有个性化交易基础方案，则读取本账户所属账户产品交易基础方案
                if(!isPersonalized01200){
                    AcpsAcctMast acct = acpsAcctMastTempQueryDAO.find(AcpsAcctMast.class, acctId);
                    if(acct != null) {
                        // 查找账户所属账户产品的交易方案信息
                        SsApSolutionRel apRel = ssApSolutionManager.findRelByProdCode(acct.getProdCode().toString(), SolutionTypeConstant.TRANS_BASIC);
                        if(null != apRel){
                            //查找账户产品的交易基础方案
                            solu01203 = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(apRel.getSolutionId(), IntTxnCd._01203.value);
                        }
                    }
                }

                if(null == solu01203 || CollectionUtils.isEmpty(solu01203.getRuleDtls())){
                    rule.setEndRefundPeriodBegin(0);
                }else{
                    rule.setEndRefundPeriodBegin(((SsTransBasicDtl)solu01203.getRuleDtls().get(0)).getRefundPeriod());
                }
            }
            // add by zhaoxubing 20170328 end
            //保证金 20170413  add by jianglijun start
            if(IntTxnCd._00501.value.equals(gopayIntTxnCd)) {
                rule.setDepositAmt(ruleDtl.getDepositAmt());//保证金金额
            }

            rule.setCreatedTs(ruleDtl.getCreateTime());
            //保证金 20170413  add by jianglijun end
            //跨境人民币进口分账add by qld 20170724
            if(IntTxnCd._01736.value.equals(gopayIntTxnCd)) {
                rule.setCbrmbImportSplit(ruleDtl.getCbrmbImportSplit());
            }
            //外卡支付保证金add by qld 20171026
            if(IntTxnCd._01740.value.equals(gopayIntTxnCd)) {
                rule.setWkDepositScale(ruleDtl.getWkDepositScale());
            }
            List<TranBasicDtlInfo> rules = new ArrayList<TranBasicDtlInfo>();
            rules.add(rule);
            ret.setDtls(rules);
        }
        return ret;
    }

    @Override
    public String saveTranBasicSoluByIntTxnCd(SsTranBasicSolution ssTranBasicSolution, String acctId, String gopayIntTxnCd) {
        try {
            if (ssTranBasicSolution == null || StringUtils.isEmpty(acctId) || StringUtils.isEmpty(gopayIntTxnCd)) {
                return "";
            }
            
            List<TranBasicDtlInfo> dtls = ssTranBasicSolution.getDtls();
            if (dtls == null || dtls.isEmpty()) {
                return "";
            }

            // 根据交易方案ID查询方案，如果方案不存在，则返回失败
            Solution solu = ssTransBasicSoluManager.load(ssTranBasicSolution.getSolutionId());
            if (solu == null) {
            	return "";
            }
            
            //如果存在，则检查该方案是否为个性化方案，如果不是，则将该方案个性化处理
        	SsAcctSolutionRel rel = ssPeSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_BASIC);
        	
        	//add by zhuliang at 2016-4-6 begin 
        	//如果有个性化方案，则判断交易码是否在个性化方案明细中存在
        	
        	boolean txnCdisExist = false;
            if(rel != null) {
                System.out.println("判断交易码是否在个性化方案明细中存在,solutionID="+rel.getSolutionId());
                solu = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(rel.getSolutionId(), gopayIntTxnCd);
                if(solu != null && solu.getRuleDtls() != null && solu.getRuleDtls().size() > 0) {
                    txnCdisExist = true;
                }
            }
            
            if(!txnCdisExist&&rel!=null){
                System.out.println("交易码是否在个性化方案明细中不存在,solutionID="+rel.getSolutionId());
                solu.getMeta().setSolutionId(rel.getSolutionId());
            }
            //add by zhuliang at 2016-4-6 end 
        	if(rel == null) {
        	     System.out.println("根据账户ID="+acctId+"没有查询到个性化方案，进行个性化保存");
        		 SolutionMeta meta = new SsTransBasicSolution();
                 meta.setSolutionId(ssTransBasicSoluManager.nextSolutionId());
                 meta.setSolutionCode(1L);
                 meta.setSolutionVersion(1L);
                 meta.setSolutionName(meta.getSolutionId() + "");
                 meta.setSolutionDesc(meta.getSolutionId() + "");
                 meta.setCreateTime(DateUtils.getSystemDate());
                 meta.setLastUpdTime(DateUtils.getSystemDate());
                 meta.setLastUpdTranCode("");
                 
                 solu.setMeta(meta);
                 
                 List<SolutionRuleDtl> rules = solu.getRuleDtls();
                 if(rules != null) {
                	 long startSq = System.currentTimeMillis();
                	 int offset = 0;
                	 for(SolutionRuleDtl rule : rules) {
                		 rule.setSq(startSq + ++offset);
                		 rule.setSolutionId(meta.getSolutionId());
                		 rule.setCreateTime(DateUtils.getSystemDate());
                         rule.setLastUpdTime(DateUtils.getSystemDate());
                         rule.setLastUpdTranCode("");
                	 }
                 }
                 
                 //个性化
                 ssTbSolutionManager.saveSsTbSolution(solu, gopayIntTxnCd, OprLevel.ACCT, acctId,ssTranBasicSolution.getAcctProdCode());
        	}

            List<SolutionRuleDtl> rules = new ArrayList<SolutionRuleDtl>();
            int offset = 1000;
            long startSq = System.currentTimeMillis();
            for (TranBasicDtlInfo dtl : dtls) {
                SsTransBasicDtl rule = new SsTransBasicDtl();
                rule.setSq(startSq + ++offset);
                rule.setSolutionId(solu.getMeta().getSolutionId());
                rule.setGopayIntTxnCd(dtl.getGopayIntTxnCd());
                rule.setIsEnable(dtl.getIsEnable());
                rule.setFeePayer(dtl.getFeePayer());
                rule.setSettleCirCle(dtl.getSettleCirCle());
                rule.setIsRefundFee(dtl.getIsRefundFee());
                rule.setLegalIncomeAcct(dtl.getLegalIncomeAcct());
                if(dtl.getTranSpCustType() != null) {
                    rule.setTranSpCustType(dtl.getTranSpCustType().value);
                }
                rule.setRefundPeriod(dtl.getRefundPeriod());
                rule.setIsOptimizingSettle(dtl.getIsOptimizingSettle());
                rule.setIsMobileNotify(dtl.getIsMobileNotify());//短信通知
                rule.setIsOverTimeRefund(dtl.getIsOverTimeRefund());
                rule.setEndRefundPeriod(dtl.getEndRefundPeriod());

                //保证金 20170413  add by jianglijun start
                if(IntTxnCd._00501.value.equals(dtl.getGopayIntTxnCd())) {
                    rule.setDepositAmt(dtl.getDepositAmt());//保证金金额
                }
                //保证金 20170413  add by jianglijun end

                //跨境人民币进口分账 add by qld 20170725
                if(IntTxnCd._01736.value.equals(dtl.getGopayIntTxnCd())) {
                    rule.setCbrmbImportSplit(dtl.getCbrmbImportSplit());
                }

                //外卡支付 add by qld 20171026
                if(IntTxnCd._01740.value.equals(dtl.getGopayIntTxnCd())) {
                    rule.setWkDepositScale(dtl.getWkDepositScale());
                }
                rule.setCreateTime(DateUtils.getSystemDate());
                rule.setLastUpdTime(DateUtils.getSystemDate());
                rule.setLastUpdTranCode("");
                //D1优化 add by lianpeng 20170717 begin
                rule.setSettlementType(dtl.getSettlementType());
                rule.setSettlementOperationType(dtl.getSettlementOperationType());
                //D1优化 add by lianpeng 20170717 end

                rules.add(rule);
            }
            solu.setRuleDtls(rules);

            ssTbSolutionManager.saveSsTbSolution(solu, gopayIntTxnCd, OprLevel.ACCT, acctId,ssTranBasicSolution.getAcctProdCode());

            // succeed
            return "";
        } catch (Exception e) {
            // 错误码
            if (e instanceof GopayCheckException) {
                return ((GopayCheckException) e).getErrCode();
            }

            // 失败
            return "";
        }
    }

    @Override
    public String  editTranBasicSoluByIntTxnCd(String gopayIntTxnCd, SsTranBasicSolution ssTranBasicSolution,String acctId) {
        try {

            if (ssTranBasicSolution == null || StringUtils.isEmpty(gopayIntTxnCd)) {
                return "";
            }

            List<TranBasicDtlInfo> dtls = ssTranBasicSolution.getDtls();
            if (dtls == null || dtls.isEmpty()) {
                return "";
            }

            // 根据交易方案ID和交易码获取不完整的交易方案（不完整的意思是指
            // 该方法得到的方案的明细仅仅和传入的交易码相关，不相关方案明细未被加载到该方案实例中）
            Solution solu = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(ssTranBasicSolution.getSolutionId(),
                    gopayIntTxnCd);
            if (solu == null) {
                return "";
            }

            List<SolutionRuleDtl> rules = new ArrayList<SolutionRuleDtl>();
            int offset = 0;
            long startSq = System.currentTimeMillis();
            for (TranBasicDtlInfo dtl : dtls) {
                SsTransBasicDtl rule = new SsTransBasicDtl();
                rule.setSq(startSq + ++offset);
                rule.setSolutionId(ssTranBasicSolution.getSolutionId());
                rule.setGopayIntTxnCd(dtl.getGopayIntTxnCd());
                rule.setIsEnable(dtl.getIsEnable());
                rule.setFeePayer(dtl.getFeePayer());
                rule.setSettleCirCle(dtl.getSettleCirCle());
                rule.setIsRefundFee(dtl.getIsRefundFee());
                rule.setLegalIncomeAcct(dtl.getLegalIncomeAcct());
                if(dtl.getTranSpCustType() != null) {
                    rule.setTranSpCustType(dtl.getTranSpCustType().value);
                }
                rule.setRefundPeriod(dtl.getRefundPeriod());
                rule.setIsOptimizingSettle(dtl.getIsOptimizingSettle());
                rule.setIsMobileNotify(dtl.getIsMobileNotify());//短信通知
                rule.setIsOverTimeRefund(dtl.getIsOverTimeRefund());
                rule.setEndRefundPeriod(dtl.getEndRefundPeriod());
                //保证金 20170413  add by jianglijun start
                if(IntTxnCd._00501.value.equals(dtl.getGopayIntTxnCd())) {
                    rule.setDepositAmt(dtl.getDepositAmt());//保证金金额
                }
                //保证金 20170413  add by jianglijun end
                //跨境人民币进口分账 add by qld 20170725
                if(IntTxnCd._01736.value.equals(dtl.getGopayIntTxnCd())) {
                    rule.setCbrmbImportSplit(dtl.getCbrmbImportSplit());
                }

                //外卡支付保证金 add by qld 20171026
                if(IntTxnCd._01740.value.equals(dtl.getGopayIntTxnCd())) {
                    rule.setWkDepositScale(dtl.getWkDepositScale());
                }
                rule.setCreateTime(DateUtils.getSystemDate());
                rule.setLastUpdTime(DateUtils.getSystemDate());
                rule.setLastUpdTranCode("");
                //D1优化 add by lianpeng 20170717 begin
                rule.setSettlementType(dtl.getSettlementType());
                rule.setSettlementOperationType(dtl.getSettlementOperationType());
                //D1优化 add by lianpeng 20170717 end
                rules.add(rule);
            }
            ssTbSolutionManager.editSsTbSolution(ssTranBasicSolution.getSolutionId(), gopayIntTxnCd, rules,ssTranBasicSolution.getAcctProdCode(),acctId);

            // succeed
            return "";
        } catch (Exception e) {
            // 错误码
            if (e instanceof GopayCheckException) {
                return ((GopayCheckException) e).getErrCode();
            }

            // 失败
            return "";
        }
    }

    /**
	 * ui-config
	 * 
	 * @return acctId
	 */
    @Override
    public SsAcctSolution findAcctUIConfigSolution(String acctId){
    	SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_UIS);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType());
        return aps;
    }
	
    @Override
    public SsAcctSolution findAcctGainSolution(String acctId) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.ACCT_GAIN);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType());
        return aps;
    }
    
    @Override
    public SsAcctSolution findAcctTransSolution(String acctId) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_TRN);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType());
        return aps;
    }

    @Override
    public SsAcctSolution findAcctFeeSolution(String acctId, String intTxnCd) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, TRANS_FEE);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType(), intTxnCd);
        return aps;
    }

    @Override
    public SsAcctSolution findAcctPayChannSolution(String acctId, String intTxnCd) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_PAYCHAN);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType(), intTxnCd);
        return aps;
    }

    /**
	 * uiconfig设置
	 * 
	 * @param ssAcctSolution
	 * @return
	 */
	public String modifyAcctUIConfigSolution(SsAcctSolution ssAcctSolution){
		return modifyAcctSolution(ssAcctSolution, SolutionTypeConstant.TRANS_UIS);
	}
	
    @Override
    public String modifyAcctTransSolution(SsAcctSolution ssAcctSolution) {
        return modifyAcctSolution(ssAcctSolution, SolutionTypeConstant.TRANS_TRN);
    }
    @Override
    public String modifyAcctGainSolution(SsAcctSolution ssAcctSolution) {
        return modifyAcctSolution(ssAcctSolution, SolutionTypeConstant.ACCT_GAIN);
    }
    @Override
    public String modifyAcctFeeSolution(SsAcctSolution ssAcctSolution, String intTxnCd) {
        return modifyAcctSolution(ssAcctSolution, intTxnCd, TRANS_FEE);
    }
    @Override
    public String modifyAcctPayChannSolution(SsAcctSolution ssAcctSolution, String intTxnCd) {
        return modifyAcctSolution(ssAcctSolution, intTxnCd, SolutionTypeConstant.TRANS_PAYCHAN);
    }
    
    /**
     * 
     * @param solutionType
     * @return
     */
    private String modifyAcctSolution(SsAcctSolution ssAcctSolution, String solutionType) {

        if (ssAcctSolution == null) {
            return "账户产品方案设置：数据为空";
        }

        String acctId = ssAcctSolution.getAcctId();

        String error = checkAcctId(acctId);
        if (null != error) {
            return error;
        }

        List<SolutionDtlInfo> transDtlInfos = ssAcctSolution.getSolutionDtls();
        if(SolutionTypeConstant.TRANS_TRN.equals(solutionType)){
            for (int i = 0, size = transDtlInfos == null ? 0 : transDtlInfos.size(); i < size; i++) {
                String intTxnCd = ((TransDtlInfo) transDtlInfos.get(i)).getGopayIntTxnCd();
                error = checkIntTxnCds(intTxnCd, solutionType);
                if (null != error) {
                    return error;
                }
            }
        }

        // 查询账户产品关系记录
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, solutionType);

        // 如果请求参数为空，则表示删除此关系记录、方案记录及明细
        if (transDtlInfos == null || transDtlInfos.isEmpty()) {
            // 1: delete rel, delete solution, delete transDtl
            ssAcctSolutionManager.deleteRelAndChild(rel, solutionType);
            return ProcCodeConstants.PROC_CODE_000S1000;
        }

        // 如果请求参数存在有效数据，但关系表不存在对应记录，则新建关系记录，并保存新方案及明细信息
        if (rel == null) {
            // 2: save rel, save solution, save transDtl
            rel = createAcctSolRel(acctId, solutionType);
            Solution s = new Solution();
            SolutionMeta meta = createSolutionMeta(solutionType);
            List<SolutionRuleDtl> dlts = createRuleDtls(transDtlInfos, null, solutionType, meta.getSolutionId());
            s.setMeta(meta);
            s.setRuleDtls(dlts);
            ssAcctSolutionManager.saveRelAndChild(rel, s);
            return ProcCodeConstants.PROC_CODE_000S1000;
        }

        // 3：solution存在，但明细不存在情况不会出现

        // 方案及明细均存在，先删除旧的明细信息，再保存新的明细信息
        Solution s = ssAcctSolutionManager.load(rel.getSolutionId(), solutionType);
        if (null != s) {
            // 4-5: delete solutin and dtl, save solution and dtl
            List<SolutionRuleDtl> dlts = createRuleDtls(transDtlInfos, null, solutionType, s.getMeta().getSolutionId());
            s.setRuleDtls(dlts);
            ssAcctSolutionManager.updateSolutionChild(s, solutionType);

            return ProcCodeConstants.PROC_CODE_000S1000;
        }

        return "方案不存在，无法操作！账户：" + acctId;
    }
    
    /**
     * 
     * @param ssAcctSolution
     * @param intTxnCd
     * @param solutionType
     */
    private String modifyAcctSolution(SsAcctSolution ssAcctSolution, String intTxnCd, String solutionType) {

        if (ssAcctSolution == null) {
            return "方案设置：数据为空." + solutionType;
        }
        String acctId = ssAcctSolution.getAcctId();
        String error = checkAcctId(acctId);
        if (null != error) {
            return error;
        }

        error = checkIntTxnCds(intTxnCd, solutionType);
        if (null != error) {
            return error;
        }

        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, solutionType);

        List<SolutionDtlInfo> dtlInfos = ssAcctSolution.getSolutionDtls();

        // 如果请求参数为空，则表示删除此关系对应方案下特定交易码的明细记录
        if (dtlInfos == null || dtlInfos.isEmpty()) {
            // 1: delete transDtl(inttxncd=gopayIntTxnCd)
//            logger.info("执行deleteRelAndChild删除"+ ToStringBuilder.reflectionToString(rel));
            ssAcctSolutionManager.deleteRelAndChild(rel, intTxnCd, solutionType,ssAcctSolution.getProdCode(),ssAcctSolution.getAcctId());
            return ProcCodeConstants.PROC_CODE_000S1000;
        }

        Map<String, Object> attrs = new HashMap<String, Object>();
        attrs.put("intTxnCd", intTxnCd);

        // 如果请求参数存在有效数据，但关系表不存在对应记录，则新建关系记录，并保存新方案及明细信息
        if (rel == null) {
            // 2: save rel, save solution, save transDtl
            rel = createAcctSolRel(acctId, solutionType);
            Solution s = new Solution();
            SolutionMeta meta = createSolutionMeta(solutionType);
            List<SolutionRuleDtl> dlts = createRuleDtls(dtlInfos, attrs, solutionType, meta.getSolutionId());
            s.setMeta(meta);
            s.setRuleDtls(dlts);
            ssAcctSolutionManager.saveRelAndChild(rel, s);
            return ProcCodeConstants.PROC_CODE_000S1000;
        }

        // 方案及明细均存在，先删除旧的明细信息，再保存新的明细信息
        Solution s = ssAcctSolutionManager.load(rel.getSolutionId(), intTxnCd, solutionType);
        if (s != null) {
            // 新的dtl赋值到solution中
            List<SolutionRuleDtl> dlts = createRuleDtls(dtlInfos, attrs, solutionType, s.getMeta().getSolutionId());
            s.setRuleDtls(dlts);
            ssAcctSolutionManager.updateSolutionChild(s, intTxnCd, solutionType,ssAcctSolution.getProdCode(),ssAcctSolution.getAcctId(),ssAcctSolution.getPayChannel());
            return ProcCodeConstants.PROC_CODE_000S1000;
        }
        return "方案不存在，无法操作！账户：" + acctId + "，交易码：" + intTxnCd;
    }
    
    /**
     * 交易方案明细记录
     * 
     * @param solutionId
     * @return
     */
    private List<SolutionRuleDtl> createRuleDtls(List<SolutionDtlInfo> params, Map<String, Object> attrs,
            String solutionType, long solutionId) {
        AtomicInteger sq = new AtomicInteger(1);
        //由于机器配置太高，采用currentTimeMillis()会导致主键冲突，改用跟精确的nanoTime()
        long nano = System.nanoTime();
        List<SolutionRuleDtl> dlts = new ArrayList<SolutionRuleDtl>();
        for (int i = 0, size = params == null ? 0 : params.size(); i < size; i++) {
            SolutionRuleDtl dtl = getSolutionRuleDtl(params.get(i), attrs, solutionType);
            dtl.setCreateTime(DateUtils.getSystemDate());
            dtl.setLastUpdTranCode("");
            dtl.setLastUpdTime(dtl.getCreateTime());
            dtl.setSolutionId(solutionId);
            dtl.setSq(nano + sq.getAndIncrement());
            dlts.add(dtl);
        }
        return dlts;
    }
    
    /**
     * 
     * @param param
     * @param solutionType
     * @return
     */
    private SolutionRuleDtl getSolutionRuleDtl(SolutionDtlInfo param, Map<String, Object> attrs, String solutionType) {
        if (TRANS_FEE.equals(solutionType)) {
            FeeDtlInfo info = (FeeDtlInfo) param;
            SsTransFeeDtl dtl = new SsTransFeeDtl();
            dtl.setAcctType(info.getAcctType());
            dtl.setCalExp(info.getCalExp());
            dtl.setGatewaySource("00");
            dtl.setFeeType(info.getFeeType());
            dtl.setGopayIntTxnCd((String) attrs.get("intTxnCd"));
            dtl.setPayChannel(info.getPayChannel());
            dtl.setRemarks(info.getRemarks());
            dtl.setDtlStatus(info.getDtlStatus());
			//跨境加上邮电费 qld
			dtl.setPostAmt(info.getPostAmt());
			dtl.setWkQuotaFeeAmt(info.getWkQuotaFeeAmt());
			dtl.setWkComplaintFeeAmt(info.getWkComplaintFeeAmt());
            dtl.setSpecType(info.getSpecType());
            dtl.setSpecExp(info.getSpecExp());
            return dtl;
        }
        if (SolutionTypeConstant.TRANS_PAYCHAN.equals(solutionType)) {
            PayChannelDtlInfo info = (PayChannelDtlInfo) param;
            SsTransPayChanDtl dtl = new SsTransPayChanDtl();
            dtl.setGopayIntTxnCd((String) attrs.get("intTxnCd"));
            dtl.setPayChannel(info.getPayChannel());
            dtl.setOutStlmId(info.getOutStlmId());
            return dtl;
        }
        if (SolutionTypeConstant.ACCT_GAIN.equals(solutionType)) {
            GainDtlInfo info = (GainDtlInfo) param;
            SsAcctGainDtl dtl = new SsAcctGainDtl();
            dtl.setAcctId(info.getAcctId());
            dtl.setBeginDate(info.getBeginDate());
            dtl.setCalExp(info.getCalExp());
            dtl.setEndDate(info.getEndDate());
            dtl.setCalTime(info.getCalTime());
            dtl.setGainsType(Integer.valueOf(info.getGainsType()));
            return dtl;
        }
        if (SolutionTypeConstant.TRANS_TRN.equals(solutionType)) {
            TransDtlInfo info = (TransDtlInfo) param;
            SsTransDtl dtl = new SsTransDtl();
            dtl.setGatewaySource("00");
            dtl.setGopayIntTxnCd(info.getGopayIntTxnCd());
            return dtl;
        }
        if (SolutionTypeConstant.TRANS_UIS.equals(solutionType)) {
            UIConfigDtlInfo info = (UIConfigDtlInfo) param;
            SsUIConfigDtl dtl = new SsUIConfigDtl();
            dtl.setAppID(info.getAppID());
            dtl.setBeginDate(info.getBeginDate());
            dtl.setConfigExp(info.getConfigExp());
            dtl.setEndDate(info.getEndDate());
            return dtl;
        }
        if (SolutionTypeConstant.GP_COM.equals(solutionType)) {
            SsComConfInfo info = (SsComConfInfo) param;
            SsGpComConfDtl dtl = new SsGpComConfDtl();
            dtl.setAcctType(info.getAcctType());
            dtl.setCalExp(info.getCalExp());
            dtl.setGatewaySource("00");
            dtl.setFeeType(info.getFeeType());
            //dtl.setGopayIntTxnCd((String) attrs.get("intTxnCd"));
            dtl.setPayChannel(info.getPayChannel());
            dtl.setRemarks(info.getRemarks());
            dtl.setDtlStatus(info.getDtlStatus());
            return dtl;
        }
        if (SolutionTypeConstant.GP_RISKFUND.equals(solutionType)) {
            SsRskConfInfo info = (SsRskConfInfo) param;
            SsGpRiskFundConfDtl dtl = new SsGpRiskFundConfDtl();
            dtl.setAcctType(info.getAcctType());
            dtl.setCalExp(info.getCalExp());
            dtl.setGatewaySource("00");
            dtl.setFeeType(info.getFeeType());
            //dtl.setGopayIntTxnCd((String) attrs.get("intTxnCd"));
            dtl.setPayChannel(info.getPayChannel());
            dtl.setRemarks(info.getRemarks());
            dtl.setDtlStatus(info.getDtlStatus());
            return dtl;
        }
        if (SolutionTypeConstant.TRANS_PROFIT.equals(solutionType)) {
            ProfitDtlInfo info = (ProfitDtlInfo) param;
            SsTransProfitDtl dtl = new SsTransProfitDtl();
            dtl.setGopayIntTxnCd((String) attrs.get("intTxnCd"));
            dtl.setGatewaySource("00");
            dtl.setTransAuth(info.getTransAuth());
            dtl.setTransStartDate(info.getTransStartDate());
            dtl.setTransEndDate(info.getTransEndDate());
            dtl.setIsEnable(info.getIsEnable());
            dtl.setAcctType(info.getAcctType());
            dtl.setCalExp(info.getCalExp());
            dtl.setPayChannel(info.getPayChannel());
            dtl.setRemarks(info.getRemarks());
            dtl.setDtlStatus(info.getDtlStatus());
            return dtl;
        }else if(SolutionTypeConstant.TRANS_SETTLE.equals(solutionType)) {
            SettleDtlInfo info = (SettleDtlInfo) param;
            SsTransSettleDtl dtl = new SsTransSettleDtl();
            dtl.setGopayIntTxnCd((String) attrs.get("intTxnCd"));
			dtl.setAcctId(info.getAcctId());
			dtl.setBankCode(info.getBankCode());
			/**自动结算优化 增加节假日判断  zhg.zhang 20160727**/
			dtl.setIsWorkDay(info.getIsWorkDay());
            return dtl;
        }
        return null;
    }
    
    /**
     * 创建一个新的方案
     * 
     * @return
     */
    private SolutionMeta createSolutionMeta(String solutionType) {
        SolutionMeta meta = null;
        if (SolutionTypeConstant.TRANS_TRN.equals(solutionType)) {
            meta = new SsTransSolution();
        } else if (TRANS_FEE.equals(solutionType)) {
            meta = new SsTransFeeSolution();
        } else if (SolutionTypeConstant.TRANS_PAYCHAN.equals(solutionType)) {
            meta = new SsTransPayChanSolution();
        } else if (SolutionTypeConstant.ACCT_GAIN.equals(solutionType)) {
            meta = new SsAcctGainsSolution();
        } else if (SolutionTypeConstant.TRANS_UIS.equals(solutionType)) {
            meta = new SsUIConfigSolution();
        } else if(SolutionTypeConstant.GP_COM.equals(solutionType)){
            meta =  new SsGpComSolution();
        } else if(SolutionTypeConstant.GP_RISKFUND.equals(solutionType)){
            meta = new SsGpRiskFundConfSolution();
        } else if (SolutionTypeConstant.TRANS_PROFIT.equals(solutionType)) {
            meta = new SsTransProfitSolution();
        } else if (SolutionTypeConstant.TRANS_SETTLE.equals(solutionType)) {
            meta = new SsTransSettleSolution();
        }
        meta.setCreateTime(DateUtils.getSystemDate());
        meta.setLastUpdTime(meta.getCreateTime());
        meta.setSolutionCode(0);
        meta.setSolutionDesc("add solution");
        meta.setSolutionId(System.currentTimeMillis());
        meta.setSolutionName("solution");
        meta.setSolutionVersion(0);
        return meta;
    }
    
    /**
     * 账户方案关系
     * 
     * @param acctId
     * @param solutionType
     * @return
     */
    private SsAcctSolutionRel createAcctSolRel(String acctId, String solutionType) {
        SsAcctSolutionRel rel = new SsAcctSolutionRel();
        rel.setCreatedTs(DateUtils.getSystemDate());
        rel.setLastUpdTs(rel.getCreatedTs());
        rel.setAcctId(acctId);
        rel.setSolutionType(solutionType);
        rel.setSq(System.currentTimeMillis());
        rel.setSolutionId(0);
        return rel;
    }
    
    /**
     * 
     * @param solutionType
     * @param intTxnCd
     * @return
     */
    private String checkIntTxnCds(String intTxnCd, String solutionType) {

        if (StringUtils.isEmpty(intTxnCd)) {
            if (SolutionTypeConstant.TRANS_TRN.equals(solutionType)
                    || SolutionTypeConstant.TRANS_UIS.equals(solutionType)) {
                return null;
            } else {
                return "交易码不能为空";
            }
        }

//        if (null == cpsTransInfoQueryDAO.find(CpsTransInfo.class, intTxnCd)) {
//            return "平台不支持的交易码：" + intTxnCd;
//        }
        return null;
    }

    
    /**
     * 检查账户
     * 
     * @param acctId
     * @return
     */
    private String checkAcctId(String acctId) {
        if (StringUtils.isBlank(acctId)) {
            return "产品代码错误: " + acctId;
        }

        // 查找账户信息
        AcpsAcctMast acct = acpsAcctMastTempQueryDAO.find(AcpsAcctMast.class, acctId);
        if (acct == null) {
            return "不存在的账户: " + acctId;
        }
        return null;
    }
    
    /**
     * 
     * @param rel
     * @return
     */
    private SsAcctSolution initSsAcctSolution(SsAcctSolutionRel rel) {
        if (null == rel) {
            return null;
        }

        SsAcctSolution aps = new SsAcctSolution();
        aps.setAcctId(rel.getAcctId());
        aps.setSsApSolutionRelSq("" + rel.getSq());
        aps.setSolutionType(rel.getSolutionType());
        aps.setSolutionId("" + rel.getSolutionId());
        return aps;
    }
    
    /**
     * 
     * @param aps
     * @param solutionType
     * @param gopayIntTxnCd
     */
    private void setSsAcctSolutionDtlInfos(SsAcctSolution aps, String solutionType, String gopayIntTxnCd) {
        if (aps == null) {
            return;
        }
        Solution s = ssAcctSolutionManager.load(Long.valueOf(aps.getSolutionId()), gopayIntTxnCd, solutionType);
        aps.setSolutionDtls(initSolutionDtlInfos(s, solutionType));
    }
    
    /**
     * @param aps
     * @param solutionType
     * @return
     */
    private void setSsAcctSolutionDtlInfos(SsAcctSolution aps, String solutionType) {
        if (aps == null) {
            return;
        }
        Solution s = ssApSolutionManager.load(Long.valueOf(aps.getSolutionId()), solutionType);
        aps.setSolutionDtls(initSolutionDtlInfos(s, solutionType));
    }
    
    /**
     * @param solution
     * @param solutionType
     * @return
     */
    private List<SolutionDtlInfo> initSolutionDtlInfos(Solution solution, String solutionType){
        if (null == solution) {
            return null;
        }
        List<SolutionRuleDtl> ruleDtls = solution.getRuleDtls();
        if (null == ruleDtls || ruleDtls.isEmpty()) {
            return null;
        }
        List<SolutionDtlInfo> list = new ArrayList<SolutionDtlInfo>();
        for (int i = 0, size = ruleDtls.size(); i < size; i++) {
            list.add(initSolutionDtlInfo(ruleDtls.get(i), solutionType));
        }
        return list;
    }
    
    private SolutionDtlInfo initSolutionDtlInfo(SolutionRuleDtl ruleDtl, String solutionType){
        if (TRANS_FEE.equals(solutionType)) {
            SsTransFeeDtl dtl = (SsTransFeeDtl) ruleDtl;
            FeeDtlInfo info = new FeeDtlInfo();
            info.setCalExp(dtl.getCalExp());
            info.setFeeType(dtl.getFeeType());
            info.setPayChannel(dtl.getPayChannel());
            info.setAcctType(dtl.getAcctType());
            info.setRemarks(dtl.getRemarks());
            info.setDtlStatus(dtl.getDtlStatus());
			//跨境的邮电费
			info.setPostAmt(dtl.getPostAmt());
			info.setWkQuotaFeeAmt(dtl.getWkQuotaFeeAmt());
			info.setWkComplaintFeeAmt(dtl.getWkComplaintFeeAmt());
            info.setSeq(dtl.getSq());
            info.setSpecExp(dtl.getSpecExp());
            info.setSpecType(dtl.getSpecType());
            info.setIntTxnCd(dtl.getGopayIntTxnCd());
            return info;
        } else if (SolutionTypeConstant.TRANS_PAYCHAN.equals(solutionType)) {
            SsTransPayChanDtl dtl = (SsTransPayChanDtl) ruleDtl;
            PayChannelDtlInfo info = new PayChannelDtlInfo();
            info.setOutStlmId(dtl.getOutStlmId());
            info.setPayChannel(dtl.getPayChannel());
            return info;
        }
        if (SolutionTypeConstant.ACCT_GAIN.equals(solutionType)) {
            SsAcctGainDtl dtl = (SsAcctGainDtl) ruleDtl;
            GainDtlInfo info = new GainDtlInfo();
            info.setAcctId(dtl.getAcctId());
            info.setBeginDate(dtl.getBeginDate());
            info.setCalExp(dtl.getCalExp());
            info.setCalTime(dtl.getCalTime());
            info.setEndDate(dtl.getEndDate());
            info.setGainsType("" + dtl.getGainsType());
            return info;
        } else if (SolutionTypeConstant.TRANS_TRN.equals(solutionType)) {
            SsTransDtl dtl = (SsTransDtl) ruleDtl;
            TransDtlInfo info = new TransDtlInfo();
            info.setGopayIntTxnCd(dtl.getGopayIntTxnCd());
            info.setGopayIntTxnName("");
            return info;
        }else if (SolutionTypeConstant.TRANS_UIS.equals(solutionType)) {
            SsUIConfigDtl dtl = (SsUIConfigDtl) ruleDtl;
            UIConfigDtlInfo info = new UIConfigDtlInfo();
            info.setAppID(dtl.getAppID());
            info.setBeginDate(dtl.getBeginDate());
            info.setEndDate(dtl.getEndDate());
            info.setConfigExp(dtl.getConfigExp());
            return info;
        }else if(SolutionTypeConstant.GP_COM.equals(solutionType)){
             SsGpComConfDtl dtl = (SsGpComConfDtl) ruleDtl;
             SsComConfInfo info = new SsComConfInfo();
            info.setCalExp(dtl.getCalExp());
            info.setFeeType(dtl.getFeeType());
            info.setPayChannel(dtl.getPayChannel());
            info.setAcctType(dtl.getAcctType());
            info.setRemarks(dtl.getRemarks());
            info.setDtlStatus(dtl.getDtlStatus());
            info.setSeq(dtl.getSq());
            return info;
        }else if(SolutionTypeConstant.GP_RISKFUND.equals(solutionType)){
            SsGpRiskFundConfDtl dtl = (SsGpRiskFundConfDtl) ruleDtl;
            SsRskConfInfo info = new SsRskConfInfo();
            info.setCalExp(dtl.getCalExp());
            info.setFeeType(dtl.getFeeType());
            info.setPayChannel(dtl.getPayChannel());
            info.setAcctType(dtl.getAcctType());
            info.setRemarks(dtl.getRemarks());
            info.setDtlStatus(dtl.getDtlStatus());
            info.setSeq(dtl.getSq());
            return info;
        } else if (SolutionTypeConstant.TRANS_PROFIT.equals(solutionType)) {
            SsTransProfitDtl dtl = (SsTransProfitDtl) ruleDtl;
            ProfitDtlInfo info = new ProfitDtlInfo();
            info.setTransAuth(dtl.getTransAuth());
            info.setTransStartDate(dtl.getTransStartDate());
            info.setTransEndDate(dtl.getTransEndDate());
            info.setIsEnable(dtl.getIsEnable());
            info.setCalExp(dtl.getCalExp());
            info.setPayChannel(dtl.getPayChannel());
            info.setAcctType(dtl.getAcctType());
            info.setRemarks(dtl.getRemarks());
            info.setDtlStatus(dtl.getDtlStatus());
            info.setSeq(dtl.getSq());
            return info;
        } else if (SolutionTypeConstant.TRANS_SETTLE.equals(solutionType)) {
        	SsTransSettleDtl dtl = (SsTransSettleDtl) ruleDtl;
        	SettleDtlInfo info = new SettleDtlInfo();
        	info.setGopayIntTxnCd(dtl.getGopayIntTxnCd());
        	info.setAcctId(dtl.getAcctId());
        	info.setBankCode(dtl.getBankCode());
            info.setSeq(dtl.getSq());  
            /**自动结算优化 增加节假日判断  zhg.zhang 20160727**/
            info.setIsWorkDay(dtl.getIsWorkDay());
            return info;
        }
        return null;
    }

    @Override
    public String modifyGpComConfSolution(SsAcctSolution ssAcctSolution) {
        return modifyAcctSolution(ssAcctSolution, SolutionTypeConstant.GP_COM);
    }

    @Override
    public String modifyGpRiskFundConfSolution(SsAcctSolution ssAcctSolution) {
        return modifyAcctSolution(ssAcctSolution, SolutionTypeConstant.GP_RISKFUND);
    }

    @Override
    public SsAcctSolution findAcctGpComConfSolution(String acctId) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.GP_COM);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType());
        return aps;
    }

   
    @Override
    public SsAcctSolution findAcctGpRiskFundConfSolution(String acctId) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.GP_RISKFUND);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType());
        return aps;
    }

    @Override
    public SsAcctSolution findAcctProfitSolution(String acctId, String intTxnCd) {
        SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_PROFIT);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType(), intTxnCd);
        return aps;
    }    
    
    @Override
    public String modifyAcctProfitSolution(SsAcctSolution ssAcctSolution, String intTxnCd) {
        return modifyAcctSolution(ssAcctSolution, intTxnCd, SolutionTypeConstant.TRANS_PROFIT);
    }

	@Override
	public SsAcctSolution findAcctSettleSolution(String acctId, String intTxnCd) {
		SsAcctSolutionRel rel = ssAcctSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_SETTLE);
        if (null == rel) {
            return null;
        }
        SsAcctSolution aps = initSsAcctSolution(rel);
        setSsAcctSolutionDtlInfos(aps, rel.getSolutionType(), intTxnCd);
        return aps;
	}

    /**
     *
     *查询特定账户指定交易基础方案信息
     * @param acctId
     * @param intTxnCds
     * @return
     */
    @Override
    public SsTranBasicSolution findAcctTransBasicSolution(String acctId, String intTxnCds) {

        Solution solu = null;
        boolean isPersonalized = false;

        SsAcctSolutionRel rel = ssPeSolutionManager.findRelByAcctId(acctId, SolutionTypeConstant.TRANS_BASIC);
        //如果有个性化方案，则直接取该方案
        if(rel != null) {
            solu = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(rel.getSolutionId(), intTxnCds);
            if(solu != null && solu.getRuleDtls() != null && solu.getRuleDtls().size() > 0) {
                isPersonalized = true;
            }
        }

        if(null == solu){// 通用方案未设定时
            return null;
        }

        List<SolutionRuleDtl> ruleDtls = solu.getRuleDtls();
        List<SsTranBasicSolution> tranBasicSolutionList = new ArrayList<SsTranBasicSolution>();

        return this.getSsTranBasicSolution(acctId, solu, isPersonalized, rel);
    }

    @Override
	public String modifyAcctSettleSolution(SsAcctSolution ssAcctSolution,
			String intTxnCd) {
		return modifyAcctSolution(ssAcctSolution, intTxnCd, SolutionTypeConstant.TRANS_SETTLE);
	}

	@Override
	public Map<String, String> findRelMapByAcctId(String acctId, String intTxnCd) {
		
		Map<String, String> result = new HashMap<>();
		result.put("msg", "success");
		if (StringUtils.isEmpty(acctId)) {
			result.put("msg", "账户为空！");
			return result;
		}
		
		if (StringUtils.isEmpty(intTxnCd)) {
			result.put("msg", "内部交易码为空！");
			return result;
		}

		String[] soluTypes = new String[solutionManagerMap.keySet().size()];
		
		int x = 0;
		for (String key : solutionManagerMap.keySet()) {
			soluTypes[x++] = key;
		}
		
		List<SsAcctSolutionRel> list = ssPeSolutionManager.findRelListByAcctId(acctId, soluTypes);
		
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				SsAcctSolutionRel rel = list.get(i);
				if (rel != null) {
					//加交易码 进行再次判断
					if (rel.getSolutionType().equals(SolutionTypeConstant.TRANS_BASIC)) {
						//基础交易方案
						Solution solu = ssTransBasicSoluManager.loadBySeqAndIntTxnCd(rel.getSolutionId(), intTxnCd);
			            if(solu != null && solu.getRuleDtls() != null && solu.getRuleDtls().size() > 0) {
			            	result.put(rel.getSolutionType(), "true");
			            }
					} else if (TRANS_FEE.equals(rel.getSolutionType())) {
						
						SsAcctSolution solution = findAcctFeeSolution(acctId, intTxnCd);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
					} else if (SolutionTypeConstant.TRANS_PAYCHAN.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctPayChannSolution(acctId, intTxnCd);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
					} else if (SolutionTypeConstant.TRANS_PROFIT.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctProfitSolution(acctId, intTxnCd);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
						
					} else if (SolutionTypeConstant.TRANS_SETTLE.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctSettleSolution(acctId, intTxnCd);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
					} else if (SolutionTypeConstant.TRANS_UIS.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctUIConfigSolution(acctId);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
                            //result.put(rel.getSolutionType(), "true"); //生产bug6期 修改前 lx 2017-7-5 11:17:43
						    Solution s = ssAcctSolutionManager.load(Long.valueOf(solution.getSolutionId()), intTxnCd, SolutionTypeConstant.TRANS_UIS);
                            result.put(rel.getSolutionType(), s.getRuleDtls() != null ? "true" : "");
                        }
					}  else if (SolutionTypeConstant.ACCT_GAIN.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctGainSolution(acctId);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
					}   else if (SolutionTypeConstant.GP_RISKFUND.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctGpRiskFundConfSolution(acctId);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
					}   else if (SolutionTypeConstant.GP_COM.equals(rel.getSolutionType())) {
						SsAcctSolution solution = findAcctGpComConfSolution(acctId);
						if (solution != null && solution.getSolutionDtls() != null && solution.getSolutionDtls().size() > 0) {
							result.put(rel.getSolutionType(), "true");
						}
					} else {
						result.put(rel.getSolutionType(), "true");
					}
				}
			}
		}
		return result;
	}
    @Override
    public List<CopyTransDtlInfo> findAcctPerSoluByAcctId(String acctId) {//只要初始化任何基础方案、手续费、付款渠道、结算就展示
        List<CopyTransDtlInfo> transDtlFeeInfosAcct= new ArrayList();//个性化手续费方案
        List<CopyTransDtlInfo> transDtlPayChanlfosAcct= new ArrayList();//个性化付款渠道方案
        List<CopyTransDtlInfo> transDtlSettleInfosAcct= new ArrayList();//个性化结算方案
        List<CopyTransDtlInfo> transDtlInfosAcctResult= new ArrayList();//个性和通用取交集的基础方案，有个性以个性为主
        Set<CopyTransDtlInfo> transDtlInfosAcctResultSet=new HashSet();

        List<CopyTransDtlInfo> transDtlInfosAp= new ArrayList();//通用的基础方案
        List<CopyTransDtlInfo> transDtlBasicInfosAcct= new ArrayList();//个性化基础方案
        List<CopyTransDtlInfo> transDtlInfosAcctSubtract= new ArrayList();//个性化与通用基础方案差集

        SsAcctSolutionRel ssAcctFeeSolution=ssAcctSolutionManager.findRelByAcctId(acctId ,SolutionTypeConstant.TRANS_FEE);//查询个性的交易手续费方案方案关系表
        if(ssAcctFeeSolution != null) {
            Solution soluFee = ssTransFeeSoluManager.load(ssAcctFeeSolution.getSolutionId());
            buildTransFeeDtl(transDtlFeeInfosAcct, soluFee);
            transDtlInfosAcctResultSet.addAll(transDtlFeeInfosAcct);
            logger.info("-----------------个性化手续费方案:"+transDtlFeeInfosAcct.size()+"----transDtlInfosAcctResultSet:"+transDtlInfosAcctResultSet.size()+"----------------------------");
        }
        SsAcctSolutionRel ssAcctPayChanSolution=ssAcctSolutionManager.findRelByAcctId(acctId ,SolutionTypeConstant.TRANS_PAYCHAN);//查询个性的交易付款渠道方案方案关系表
        if(ssAcctPayChanSolution != null) {
            Solution soluPayChanl = ssTransPayChanSoluManager.load(ssAcctPayChanSolution.getSolutionId());
            buildTransPayChanlDtl(transDtlPayChanlfosAcct, soluPayChanl);
            transDtlInfosAcctResultSet.addAll(transDtlPayChanlfosAcct);
            logger.info("-----------------个性化付款渠道方案:"+transDtlPayChanlfosAcct.size()+"----transDtlInfosAcctResultSet:"+transDtlInfosAcctResultSet.size()+"----------------------------");
        }
        SsAcctSolutionRel ssAcctSettleSolution=ssAcctSolutionManager.findRelByAcctId(acctId ,SolutionTypeConstant.TRANS_SETTLE);//查询个性的交易结算方案方案关系表
        if(ssAcctSettleSolution != null) {
            Solution soluSettle = ssTransSettleSoluManager.load(ssAcctSettleSolution.getSolutionId());
            buildTransSettleDtl(transDtlSettleInfosAcct, soluSettle);
            transDtlInfosAcctResultSet.addAll(transDtlSettleInfosAcct);
            logger.info("-----------------个性化结算渠道方案:"+transDtlPayChanlfosAcct.size()+"----transDtlInfosAcctResultSet:"+transDtlInfosAcctResultSet.size()+"----------------------------");
        }

        SsApSolutionRel ssApSolutionRel = ssApSolutionManager.findRelByProdCode(AcctProd.GNST.name(), SolutionTypeConstant.TRANS_BASIC);//查询通用基础方案
        if (ssApSolutionRel == null) {
            // 暂时不做处理，返回空List即可
            return transDtlInfosAp;
        }
        Solution soluAp = ssTransBasicSoluManager.load(ssApSolutionRel.getSolutionId());
        if (soluAp == null) {
            // 暂时不做处理，返回空List即可
            return transDtlInfosAp;
        }
        buildTransBasicDtl(transDtlInfosAp,soluAp);//封装返回通用基础方案
        logger.info("-----------------通用化基础方案:"+transDtlInfosAp.size()+"--------------------------------");
        SsAcctSolutionRel ssAcctSolution=ssAcctSolutionManager.findRelByAcctId(acctId ,SolutionTypeConstant.TRANS_BASIC);//查询个性的基础方案关系表
        if(ssAcctSolution!=null) {
            Solution solu = ssTransBasicSoluManager.load(ssAcctSolution.getSolutionId());
            buildTransBasicDtl(transDtlBasicInfosAcct, solu);////封装返回个性基础方案
            transDtlInfosAcctResultSet.addAll(transDtlBasicInfosAcct);
            logger.info("-----------------个性化基础方案:" + transDtlBasicInfosAcct.size() + "------transDtlInfosAcctResultSet:"+transDtlInfosAcctResultSet.size()+"--------------------------");
            transDtlInfosAcctSubtract = (List<CopyTransDtlInfo>) org.apache.commons.collections.CollectionUtils.subtract(transDtlInfosAp, transDtlBasicInfosAcct);//个性与通用取差集，个性优先
            transDtlInfosAcctResult.addAll(transDtlInfosAcctSubtract);//没有初始化的
            transDtlInfosAcctResult.addAll(transDtlBasicInfosAcct);//全部个性化基础方案
            transDtlInfosAcctResult=(List<CopyTransDtlInfo>) org.apache.commons.collections.CollectionUtils.intersection(transDtlInfosAcctResult, transDtlInfosAcctResultSet);//个性与通用取差集，个性优先
        }else{
//            transDtlInfosAcctResultSet.retainAll(transDtlInfosAp);
            transDtlInfosAcctResult=(List<CopyTransDtlInfo>) org.apache.commons.collections.CollectionUtils.intersection(transDtlInfosAp, transDtlInfosAcctResultSet);//个性与通用取差集，个性优先
        }
        logger.info("-----------------最终个性化方案:"+transDtlInfosAcctResult.size()+"--------------------------------");
        return transDtlInfosAcctResult;
    }
    /**
     * 用于基础方案封装List<CopyTransDtlInfo>
     * @param transDtl
     * @param solu
     */
    private void buildTransBasicDtl(List<CopyTransDtlInfo> transDtl, Solution solu){
        if(solu!=null) {
            List<SolutionRuleDtl> rules = solu.getRuleDtls();
            if (rules != null) {//封装到CopyTransDtlInfo得到基础方案
                for (SolutionRuleDtl rule : rules) {
                    SsTransBasicDtl ruleDtl = (SsTransBasicDtl) rule;
                    CopyTransDtlInfo dtl = new CopyTransDtlInfo();
                    dtl.setGopayIntTxnCd(ruleDtl.getGopayIntTxnCd());
                    int flag = ruleDtl.getIsEnable();
                    if (1 == flag) {//是否开通 0 - 否1 - 是
                        dtl.setAvaliable(true);
                    } else {
                        dtl.setAvaliable(false);
                    }
                    transDtl.add(dtl);
                }
            }
        }
    }
    /**
     * 用于付款渠道方案封装List<CopyTransDtlInfo>
     * @param transDtl
     * @param solu
     */
    private void buildTransPayChanlDtl(List<CopyTransDtlInfo> transDtl, Solution solu){
        if(solu!=null) {
            List<SolutionRuleDtl> rules = solu.getRuleDtls();
            if (rules != null) {//封装到CopyTransDtlInfo得到付款渠道
                for (SolutionRuleDtl rule : rules) {
                    SsTransPayChanDtl ruleDtl = (SsTransPayChanDtl) rule;
                    CopyTransDtlInfo dtl = new CopyTransDtlInfo();
                    dtl.setGopayIntTxnCd(ruleDtl.getGopayIntTxnCd());
                    dtl.setAvaliable(true);
                    transDtl.add(dtl);
                }
            }
        }
    }
    /**
     * 用于有续费方案封装List<CopyTransDtlInfo>
     * @param transDtl
     * @param solu
     */
    private void buildTransFeeDtl(List<CopyTransDtlInfo> transDtl, Solution solu){
        if(solu!=null) {
            List<SolutionRuleDtl> rules = solu.getRuleDtls();
            if (rules != null) {//封装到CopyTransDtlInfo得到付款渠道
                for (SolutionRuleDtl rule : rules) {
                    SsTransFeeDtl ruleDtl = (SsTransFeeDtl) rule;
                    CopyTransDtlInfo dtl = new CopyTransDtlInfo();
                    dtl.setGopayIntTxnCd(ruleDtl.getGopayIntTxnCd());
                    dtl.setAvaliable(true);
                    transDtl.add(dtl);
                }
            }
        }
    }
    /**
     * 用于结算方案封装List<CopyTransDtlInfo>
     * @param transDtl
     * @param solu
     */
    private void buildTransSettleDtl(List<CopyTransDtlInfo> transDtl, Solution solu) {
        if (solu!=null) {
            List<SolutionRuleDtl> rules = solu.getRuleDtls();
            if (rules != null) {//封装到CopyTransDtlInfo得到付款渠道
                for (SolutionRuleDtl rule : rules) {
                    SsTransSettleDtl ruleDtl = (SsTransSettleDtl) rule;
                    CopyTransDtlInfo dtl = new CopyTransDtlInfo();
                    dtl.setGopayIntTxnCd(ruleDtl.getGopayIntTxnCd());
                    dtl.setAvaliable(true);
                    transDtl.add(dtl);
                }
            }
        }
    }
}
